﻿import { h, defineComponent, resolveComponent } from 'vue'

import { ElRow, ElCol, ElTabs, ElTabPane, ElButton, ElCollapse, ElCollapseItem, ElCard } from 'element-plus'
import MyFormItem from './MyFormItem.js'
import MyGrid from './MyGrid.vue'
import MyListPage from './MyListPage.vue'
import MyRow from './MyRow.vue'
import MyTabPane from './MyTabPane.vue'
import _Utils from './Utils.js';

const myFormRow = defineComponent({
    name: "MyFormRow",
    emits: ["update:modelValue"],
    props: {
        tb: {
            type: Object,
            required: true
        },
        row: {
            type: [Object,String],
            required: true
        },
        formData: {
            type: Object,
            required: true
        },
        computeData: {
            type: Object,
            default: {}
        },
    },

    data(){
        return {
            row2:{}
        }
    },
    created(){
        this.row2 = (typeof(this.row)=="string")?_Utils.string2rows(this.row)[0]:this.row;
    },
    render() {
        if(this.row2){
            return this.getContain(this.row2);
        }
    },
    watch:{
        row(){
            this.row2 = (typeof(this.row)=="string")?_Utils.string2rows(this.row)[0]:this.row;
        }
    },
    methods: {
        //给formData添加一个get方法， 用于取多层数据
        getFormData(key) {
            const keys = key.split(".").filter(p => p.length > 0);
            let val = this.formData;
            keys.forEach(p => {
                if (val) {
                    val = val[p];
                }
            });
            return val;
        },
        setFormData(key, value) {
            const keys = key.split(".").filter(p => p.length > 0);
            let val = this.formData;
            let pitem = val;
            let pfield = null;
            keys.forEach(p => {
                if (val) {
                    pitem = val;
                    val = val[p];
                } else {
                    pitem = null;
                }
                pfield = p;
            });
            if (pitem) {
                pitem[pfield] = value;
            }
        },

        getContain(item, ix) {
            item = item || this.row;
            if (item.vif == false) return;
            if (item.vif) {
                if (typeof (item.vif) == "string") {
                    let vifvalue = this.computeData[item.vif];
                    if (vifvalue == false) return;
                }
            }

            switch (item.type) {
                case "html":
                    return this.getHtmlTag(item);
                case "item":
                    return this.getItem(item);
                case "row":
                    return this.getRow(item);
                case "col":
                    return this.getCol(item);
                case "tabs":
                    return this.getTabs(item);
                case "tab":
                    return this.getTab(item, ix);
                case "card":
                    return this.getCard(item);
                case "collapse":
                    return this.getCollapse(item);
                case "grid":
                    return this.getGrid(item);
                case "listPage":
                    return this.getListPage(item);
                case "button":
                    return h(ElButton, item.button, item.label);
            }
            return h("div", {}, item.type)
        },

        getListPage(item) {
            let attr = { ...item.listPage };
            attr.formData = this.formData;
            return h(MyListPage, attr);
        },
        getGrid(item) {
            if (!item.grid.search) {
                item.grid.search = {};
            }
            let attr = { ...item.grid };
            attr.formData = this.formData;
            attr['onUpdate:search'] = (value) => {
                item.grid.search = value;
            };
            return h(MyGrid, attr);
        },
        getHtmlTag(item) {
            let attr = { ...item.attr };
            let cmp = resolveComponent(item.tag);
            if (!item.items) {
                return h(cmp, attr);
            }
            return h(cmp, attr, {
                default: () => {
                    var items = [];
                    item.items.forEach((p, ix) => {
                        var item = this.getContain(p, ix);
                        if (item) {
                            items.push(item);
                        }
                    })
                    return items;
                }
            });
        },
        getItem(item) {
            if (item.vif == false) return;
            if (item.vif) {
                if (typeof (item.vif) == "string") {
                    let vifvalue = this.computeData[item.vif];
                    if (vifvalue == false) return;
                }
            }

            if (typeof (item.field) == "string") {
                let fd = this.tb.columns.filter(p => p.code == item.field)[0];
                if (fd == undefined) {
                    console.log("找不到字段定义：" + item.field)
                    return;
                }
                item.field = fd;
            }
            var field = item.field || item;


            //字段名以下划线开头的字段，是动态计算字段
            var isCompute = field.code.startsWith("_");
            var modelValue = null;
            if (isCompute) {
                modelValue = this.computeData[field.code];
            } else {
                if (field.code.indexOf(".") != -1) {
                    modelValue = this.getFormData(field.code);
                } else {
                    modelValue = this.formData[field.code];
                }
            }
            var cfg = {
                ref: "_ref_" + field.code,
                ...item["item"],
                field: field,
                modelValue: modelValue,
                computeData: this.computeData,
                formData: this.formData,
                tb: this.tb,
                'onUpdate:modelValue': (value) => {
                    if (isCompute) {
                        this.computeData[field.code] = value;
                    } else {
                        if (field.code.indexOf(".") != -1) {
                            this.setFormData(field.code, value);
                        } else {
                            this.formData[field.code] = value;
                        }
                    }
                }
            };
            return h(MyFormItem, cfg);
        },
        getCard(item) {
            let attr = { ...item["card"] }

            return h(ElCard, attr, {
                default: () => {
                    var items = [];
                    item.items.forEach(p => {
                        var item = this.getContain(p);
                        if (item) {
                            items.push(item);
                        }
                    })
                    return items;
                }
            });
        },
        getCollapse(item) {
            let attr = { ...item["collapse"] }
            attr.accordion = true;

            return h(ElCollapse, attr, {
                default: () => {
                    var items = [];
                    item.items.forEach(p => {
                        var item = this.getCollapseItem(p);
                        items.push(item);
                    })
                    return items;
                }
            });
        },
        getCollapseItem(item) {
            let attr = { title: item["item"].label };
            return h(ElCollapseItem, attr, {
                default: () => {
                    var items = [];
                    item.items.forEach(p => {
                        var item = this.getContain(p);
                        if (item) {
                            items.push(item);
                        }
                    })
                    return items;
                }
            });
        },
        getTabs(item) {
            let attr = { ...item["tabs"] };
            if (attr.modelValue == undefined) {
                attr.modelValue = "0";
            }
            return h(ElTabs, attr, {
                default: () => {
                    if (!item.items) {
                        return;
                    }
                    var items = [];
                    item.items.forEach((p, ix) => {
                        var item = this.getContain(p, ix);
                        if (item) {
                            items.push(item);
                        }
                    })
                    return items;
                }
            });
        },
        getTab(item, ix) {
            let attr = { ...item["tab"] }
            if (!attr.name) {
                ix = ix || "0";
                attr.name = String(ix);
            }
            attr.lazy = false;
            return h(MyTabPane, attr, {
                default: () => {
                    if(!item.items){
                        return;
                    }
                    var items = [];
                    item.items.forEach(p => {
                        var item = this.getContain(p);
                        if (item) {
                            items.push(item);
                        }
                    })
                    return items;
                }
            });
        },
        getRow(item) {
            const pp = {...item["row"], computeData: this.computeData, tb:this.tb, formData:this.formData};
            //const comp = (pp && pp.label && pp.label.length > 0) ? MyRow : ElRow;
            return h(MyRow, pp, {
                default: () => {
                    var items = [];
                    item.items.forEach(p => {
                        var item = this.getContain(p);
                        if (item) {
                            items.push(item);
                        }
                    })
                    return items;
                }
            });
        },
        getCol(item) {
            return h(ElCol, item["col"], {
                default: () => {
                    var items = [];
                    if (!item.fields) {
                        item.fields = this.getCols(this.tb.columns, item.field, item);
                    }
                    item.fields.forEach(p => {
                        var item = this.getItem(p);
                        items.push(item);
                    })
                    if (item.items) {
                        item.items.forEach(p => {
                            var item = this.getItem(p);
                            items.push(item);
                        })
                    }
                    return items;
                }
            });
        },
        getCols(columns, fields, col) {
            var items = [];
            var cols = (fields || "").split(",").filter(p => p.trim() != "");
            for (var ix = 0; ix < cols.length; ix++) {
                var tag = cols[ix].trim();
                var item = columns.filter(p => p.code == tag);
                if (item.length > 0) {
                    let field = item[0];
                    if (field.code in col) {
                        let fcode = field.code;
                        if (fcode == "type") {
                            fcode = "_type";
                        }
                        field.item = { ...field.item, ...col[fcode] };
                    };
                    items.push(field);
                }
            }
            return items;
        },
    }
})

export default myFormRow;